package com.team.recruitment_management_system.service.impl;

import com.team.recruitment_management_system.mapper.SysUserMapper;
import com.team.recruitment_management_system.pojo.dto.chat.ChangeChatListDto;
import com.team.recruitment_management_system.pojo.dto.message.AddChangeMessageDto;
import com.team.recruitment_management_system.pojo.vo.chat.ChatMessageVo;
import com.team.recruitment_management_system.service.ChatListService;
import com.team.recruitment_management_system.service.ChatMessageService;
import com.team.recruitment_management_system.util.JwtHelper;
import io.swagger.v3.core.util.Json;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnError;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;

/**
 * {@code @Description}:token是当前登陆用户的用户名
 * targetUsername是聊天信息接收方用户名
 */
@Component
@ServerEndpoint(value = "/chat/{targetUsername}/{token}")
public class ChatWebSocketServer {

    private static RedisTemplate<String, Object> redisTemplate;
    private static JwtHelper jwtHelper;
    private static ChatMessageService chatMessageService;
    private static ChatListService chatListService;
    @Autowired
    private ExecutorService myThreadPool;

    private static SysUserMapper sysUserMapper;

    private final static Logger log = LoggerFactory.getLogger(ChatWebSocketServer.class);
    private Session session;
    private static final ConcurrentHashMap<String, ChatWebSocketServer> websocketMap = new ConcurrentHashMap<>();
    private String currentUsername;

    @Autowired
    public void setChatMessageService(ChatMessageService chatMessageService) {
        log.info("setChatMessageService===>{}", chatMessageService);
        ChatWebSocketServer.chatMessageService = chatMessageService;
    }

    @Autowired
    public void setChatListService(ChatListService chatListService) {
        log.info("setChatListService===>{}", chatListService);
        ChatWebSocketServer.chatListService = chatListService;
    }

    @Autowired
    public void setJwtHelper(JwtHelper jwtHelper) {
        ChatWebSocketServer.jwtHelper = jwtHelper;
    }

    @Autowired
    public void setSysUserMapper(SysUserMapper sysUserMapper) {
        ChatWebSocketServer.sysUserMapper = sysUserMapper;
    }

    /**
     * 连接成功后调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("token") String token, @PathParam("targetUsername") String targetUsername) {
        log.info("websocket连接成功！");
        int userId = jwtHelper.getUserId(token);
        String username = sysUserMapper.getUsernameById(userId);
        this.session = session;
        websocketMap.put(username, this); //加入map中
        this.currentUsername = username;
        try {
            memor(currentUsername, targetUsername);
        } catch (Exception e) {
            log.error("websocket IO异常" + e.getMessage());
        }
    }

    @OnClose
    public void onClose() {
        if (this.currentUsername != null && websocketMap.get(this.currentUsername) != null) {
            websocketMap.remove(this.currentUsername);  //从map中删除
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误" + error.getMessage());
    }

    public void sendMessage(String message) throws IOException {
        log.info("发送成功...");
        this.session.getBasicRemote().sendText(message);
    }

    //    自定义消息推送
    public void sendMessage(AddChangeMessageDto addChangeMessageDto) {
        ChatMessageVo chatMessageVo = new ChatMessageVo();
        BeanUtils.copyProperties(addChangeMessageDto,chatMessageVo);
        chatMessageVo.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        if (StringUtils.isNotBlank(addChangeMessageDto.getMessage())) {
            //发送信息
            ChatWebSocketServer webSocketServer = websocketMap.get(addChangeMessageDto.getRecipientUsername());
            if (webSocketServer != null) {
                log.info("webSocketServer...");
                try {
                    webSocketServer.sendMessage(Json.pretty(chatMessageVo));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            CompletableFuture.runAsync(() -> {
                //保存聊天列表
                ChangeChatListDto changeChatListDto = new ChangeChatListDto();
                changeChatListDto.setJobId(addChangeMessageDto.getJobId());
                changeChatListDto.setResumeId(addChangeMessageDto.getResumeId());
                changeChatListDto.setRecentMessage(addChangeMessageDto.getMessage());
                chatListService.changeChatHrList(changeChatListDto);
                chatListService.changeChatSeekerList(changeChatListDto);
            }, myThreadPool);
//            回显消息
            ChatWebSocketServer webSocket = websocketMap.get(addChangeMessageDto.getSenderUsername());
            if (webSocket != null) {
                try {
                    webSocket.sendMessage(Json.pretty(chatMessageVo));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    //    推送缓存信息
    public void memor(String currentUsername, String targetUsername) {
        List<ChatMessageVo> chatMessages = chatMessageService.getAll(currentUsername, targetUsername);
        chatMessages.forEach(message -> {
            try {
                ChatWebSocketServer webSocketServer = websocketMap.get(currentUsername);
                if (webSocketServer != null) {
                    webSocketServer.sendMessage(Json.pretty(message));
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
    }
}